#include "battery.h"

Battery::Battery(QWidget *parent) : QWidget(parent)
{
    _minValue = 0;
    _maxValue = 100;
    _value = 0;
    _alarmValue = 30;
    _step = 0.5;

    _borderColorStart = QColor(100, 100, 100);
    _borderColorEnd = QColor(80, 80, 80);
    _alarmColorStart = QColor(250, 118, 113);
    _alarmColorEnd = QColor(204, 38, 38);
    _normalColorStart = QColor(50, 205, 51);
    _normalColorEnd = QColor(60, 179, 133);

    isForward = false;
    currentValue = 0;

    timer = new QTimer(this);
    timer->setInterval(10);
    connect(timer,&QTimer::timeout,this,&Battery::updateValue);
}

Battery::~Battery()
{
    if(timer->isActive())
        timer->stop();
}

void Battery::paintEvent(QPaintEvent *)
{
    //绘制准备工作，启用反锯齿
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    //绘制边框
    drawBorder(&painter);
    //绘制背景
    drawBg(&painter);
}

void Battery::drawBorder(QPainter *painter)
{
    painter->save();
    double headWidth = width() / 10;
    double batteryWidth = width() - headWidth;

    //绘制电池边框
    QPointF topLeft(5, 5);
    QPointF bottomRight(batteryWidth, height() - 5);
    batteryRect = QRectF(topLeft, bottomRight);

    painter->setPen(QPen(borderColorStart(), 5));
    painter->setBrush(Qt::NoBrush);
    painter->drawRoundedRect(batteryRect, 10, 20);

    //绘制电池头部
    QPointF headRectTopLeft(batteryRect.topRight().x(), height() / 3);
    QPointF headRectBottomRight(width(), height() - height() / 3);
    QRectF headRect(headRectTopLeft, headRectBottomRight);

    QLinearGradient headRectGradient(headRect.topLeft(), headRect.bottomLeft());
    headRectGradient.setColorAt(0.0, borderColorStart());
    headRectGradient.setColorAt(1.0, borderColorEnd());

    painter->setBrush(headRectGradient);
    painter->drawRoundRect(headRect, 15, 25);
    painter->restore();
}

void Battery::drawBg(QPainter *painter)
{
    painter->save();
    QLinearGradient batteryGradient(QPointF(0,0), QPointF(0,height()));

    if(currentValue <= alarmValue())
    {
        batteryGradient.setColorAt(0.0, alarmColorStart());
        batteryGradient.setColorAt(1.0, alarmColorEnd());
    }
    else
    {
        batteryGradient.setColorAt(0.0, normalColorStart());
        batteryGradient.setColorAt(1.0, normalColorEnd());
    }

    painter->setPen(Qt::NoPen);
    painter->setBrush(batteryGradient);

    int margin = qMin(width(), height() / 20);
    double unit = (batteryRect.width() - (margin*2)) / 100;
    double width = currentValue * unit;
    QPointF topLeft(batteryRect.topLeft().x()+margin, batteryRect.topLeft().y()+margin);
    QPointF bottomRight(width+margin+5, batteryRect.bottomRight().y()-margin);
    QRectF rect(topLeft, bottomRight);

    painter->drawRoundRect(rect, 10, 10);
    painter->restore();
}

void Battery::updateValue()
{
    if (isForward)
    {
        currentValue -= step();
        if (currentValue <= value())
        {
            timer->stop();
        }
    }
    else
    {
        currentValue += step();
        if (currentValue >= value()) {
            timer->stop();
        }
    }
    update();
}

void Battery::setRange(double minValue_, double maxValue_)
{
    //如果最小值大于或者等于最大值则不设置
    if (minValue_ >= maxValue_)
    {
        return;
    }
    _minValue = minValue_;
    _maxValue = maxValue_;

    //如果目标值不在范围值内,则重新设置目标值
    if (value() < minValue() || value() > maxValue()) {
        setValue(value());
    }

    update();

}

void Battery::setRange(int minValue_, int maxValue_)
{
    setRange((double)minValue_, (double)maxValue_);
}

void Battery::setMinValue(double minValue_)
{
    setRange(minValue_, maxValue());
}

void Battery::setMaxValue(double maxValue_)
{
    setRange(minValue(), maxValue_);
}

void Battery::setValue(double value_)
{
    //值小于最小值或者值大于最大值或者值和当前值一致则无需处理
    if (value_ < minValue() || value_ > maxValue() || value_ == _value)
    {
        return;
    }

    emit valueChanged(value_);
    _value = value_;

    if (value_ > currentValue)
    {
        isForward = false;
    }
    else if (value_ < currentValue)
    {
        isForward = true;
    }
    else
    {
        return ;
    }

    timer->start();
    update();
}

void Battery::setValue(int value_)
{
    setValue((double)value_);
}

void Battery::setAlarmValue(double alarmValue_)
{
    if (_alarmValue != alarmValue_)
    {
        _alarmValue = alarmValue_;
        update();
    }
}

void Battery::setAlarmValue(int alarmValue_)
{
    setAlarmValue((double)alarmValue_);
}

void Battery::setStep(double step_)
{
    if (_step != step_)
    {
        _step = step_;
        update();
    }
}

void Battery::setStep(int step_)
{
    setStep((double)step_);
}

void Battery::setBorderColorStart(const QColor &borderColorStart_)
{
    if (_borderColorStart != borderColorStart_)
    {
        _borderColorStart = borderColorStart_;
        update();
    }
}

void Battery::setBorderColorEnd(const QColor &borderColorEnd_)
{
    if (_borderColorEnd != borderColorEnd_)
    {
        _borderColorEnd = borderColorEnd_;
        update();
    }
}

void Battery::setAlarmColorStart(const QColor &alarmColorStart_)
{
    if (_alarmColorStart != alarmColorStart_)
    {
        _alarmColorStart = alarmColorStart_;
        update();
    }
}

void Battery::setAlarmColorEnd(const QColor &alarmColorEnd_)
{
    if (_alarmColorEnd != alarmColorEnd_)
    {
        _alarmColorEnd = alarmColorEnd_;
        update();
    }
}

void Battery::setNormalColorStart(const QColor &normalColorStart_)
{
    if (_normalColorStart != normalColorStart_)
    {
        _normalColorStart = normalColorStart_;
        update();
    }
}

void Battery::setNormalColorEnd(const QColor &normalColorEnd_)
{
    if (_normalColorEnd != normalColorEnd_) {
        _normalColorEnd = normalColorEnd_;
        update();
    }
}

